﻿using Ocelot.Configuration;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using Polly.Retry;
using Polly.Timeout;
using Ocelot.Logging;
using Polly;
using System.Linq;
using Brc_DSB.GetWay.DataBase;
using Brc_DSB.GetWay.Model;

namespace Brc_DSB.GetWay.Polly
{
    public class PollyRetryProvider
    {
        private readonly AsyncRetryPolicy _retrypolicy;
        private readonly AsyncTimeoutPolicy _timeoutPolicy;
        public PollyRetryProvider(IRetryRepository retry,DownstreamReRoute route, IOcelotLoggerFactory _logger)
        {
            var Logger = _logger.CreateLogger<PollyRetryProvider>();
            var path = route.UpstreamPathTemplate.OriginalValue;
            TimeoutStrategy strategy= TimeoutStrategy.Pessimistic;
            GetWay_ReRouteRetry retryPolicy = retry.GetRetryPolicy(path).Result;            
            if (retryPolicy!=null)
            {
                _timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(retryPolicy.TimeOutValue), strategy);
                _retrypolicy = Policy.Handle<HttpRequestException>().Or<TimeoutRejectedException>().Or<TimeoutException>().Or<Exception>().RetryAsync(retryPolicy.RetryCount,
                    (e,i)=> {
                        Logger.LogInformation($"路径为{route.UpstreamPathTemplate.OriginalValue}的请求发生异常，已经进行第{i}次重试，异常为{e.Message}");
                    });
            }
            else
            {
                _retrypolicy = null;
            }

            RetryPolicy = new Retry(_retrypolicy, _timeoutPolicy);
        }
        public Retry RetryPolicy { get; set; }
    }

    public class Retry
    {
        private readonly List<IAsyncPolicy> _policies = new List<IAsyncPolicy>();

        public Retry(params IAsyncPolicy[] policies)
        {
            foreach (var policy in policies.Where(p => p != null))
            {
                this._policies.Add(policy);
            }
        }

        public IAsyncPolicy[] Policies => this._policies.ToArray();
    }
}
